#ifndef __COMMON__
#define __COMMON__

#include <memory>
#include <vector>
#include <random>
#include <iostream>
#include <string>

/*Needed constants*/

//#define MULTIPLE_FRAMES
#define SINGLE_FRAME


#define ANTI_ALIASING 1
#define ANTI_ALIASING_CONSTANT 5
#define NUMBER_OF_SAMPLES = 25
const float invRAND_MAX = 1.0 / 32767;

#define DOT(A,B)		(A.x*B.x+A.y*B.y+A.z*B.z)
#define NORMALIZE(A)	{float l=1/sqrtf(A.x*A.x+A.y*A.y+A.z*A.z);A.x*=l;A.y*=l;A.z*=l;}
#define LENGTH(A)		(sqrtf(A.x*A.x+A.y*A.y+A.z*A.z))
#define SQRLENGTH(A)	(A.x*A.x+A.y*A.y+A.z*A.z)
#define SQRDISTANCE(A,B) ((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)+(A.z-B.z)*(A.z-B.z)


using std::string;



//#define DEBUG_MODE

typedef int Pixel;

//if not unix define 
#ifndef __unix__  
#define PI_NUM 3.141592653589793
#endif

using namespace std;
const float kHugeValue = 1 * 10 ^ 6;
const float kEpsilon = 1e-4;

static float GenrateRandomNumber(int p_minBound, int p_maxBound)
{
	std::random_device rd;
	std::mt19937 gen(rd());
	std::uniform_real_distribution<> dis(p_minBound, p_maxBound);

	return dis(gen);
}

double phi(int j)
{
	double x = 0.0;
	double f = 0.5;

	while (j)
	{
		x += f * (double)(!j & 1);
		j /= 2;
		f *= 0.5;
	}

	return x;
}

static void Print(string p_toPrint)
{
	std::cout << p_toPrint << std::endl;
}

template<typename T>
static bool deleteAll(T* theElement) 
{
	delete theElement; return true; 
}

template<typename T>
static void DeleteVector(std::vector<T>& toDelete)
{
	std::for_each(toDelete.begin(), toDelete.end(), std::default_delete<T>());
}

template <class T>
static void EmptyPointerVector(vector<T*>& deleteme) {
	while (!deleteme.empty()) {
		delete deleteme.back();
		deleteme.pop_back();
	}

	//delete deleteme;
}

#endif // !__COMMON__
